package name.marz.to.go.ahg.core;

import java.util.logging.Level;
import java.util.logging.Logger;

import name.marz.to.go.ahg.core.exception.UserProcessException;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

/**
 * 
 * @author mgoto
 *
 */
public abstract class AbstractMain {
	private static final Logger log = Logger.getLogger(AbstractMain.class.getName());

	/**
	 * メインルーチン
	 * @param args
	 */
	public void Main(String[] args) {
		try {
			parseArgs(args);
		} catch (Exception e) {
			System.exit(1);
		}
			
		int status = 0;
		log.info("開始");
		try {
			log.info("準備処理");
			ready();
			log.info("主処理");
			go();
		} catch ( UserProcessException upe ) {
			log.log(Level.SEVERE,"エラーが発生しました。"+upe.getClass().getName()+":"+upe.getMessage());
			log.log(Level.SEVERE,"中断します");
		} catch (Exception e) {
			log.log(Level.SEVERE,"システムエラーが発生しました。中断します",e);
			status = 1;
		} finally {
			log.info("終了処理");
			finish();
		}
		log.info("終了");
		System.exit(status);

	}

	/**
	 * 準備処理
	 * @throws Exception
	 */
	protected void ready() throws Exception {
	}

	/**
	 * 主処理
	 * @throws Exception
	 */
	abstract protected void go() throws Exception;
	
	/**
	 * 終了処理
	 */
	protected void finish() {
	}
	
	private void parseArgs(String[] args) {
		Options options = getOptions();
		BasicParser parser = new BasicParser();
		try {
			CommandLine cmd = parser.parse(options, args);
			setParams(cmd);
		} catch (ParseException e) {
			System.out.println(e.getMessage());
			HelpFormatter hf = new HelpFormatter();
			hf.printHelp("java "+this.getClass().getName(), options,true);
			throw new IllegalArgumentException(e);
		}
	}

	/**
	 * 
	 * @return コマンドラインオプション
	 */
	abstract protected Options getOptions();
	/**
	 * 
	 * @param cmd 解析済みのコマンドライン
	 */
	abstract protected void setParams(CommandLine cmd);
	
}
